#include "Curl.h"

long easyCURL::m_port = 8799L;
wxString easyCURL::m_proxy = wxEmptyString;
wxString easyCURL::m_proxyUsername =
    wxEmptyString;
wxString easyCURL::m_proxyPassword =
    wxEmptyString;


easyCURL::easyCURL ()
{
    customHeader = NULL;
    formPost     = NULL;
    lastPtr      = NULL;
    ch = curl_easy_init ();
    
    if ( ch != NULL ) {
        // set general libcurl options
        curl_easy_setopt ( ch, CURLOPT_WRITEFUNCTION,
                           easyCURL::ReceiveContent );
        curl_easy_setopt ( ch, CURLOPT_WRITEDATA, this );
        curl_easy_setopt ( ch, CURLOPT_USERAGENT,
                           DEFAULT_USER_AGENT );
        curl_easy_setopt ( ch, CURLOPT_FAILONERROR, 1L );
        /* pass the struct pointer into the progress function */
        curl_easy_setopt ( ch, CURLOPT_PROGRESSFUNCTION,
                           easyCURL::UploadProgress );
        curl_easy_setopt ( ch, CURLOPT_PROGRESSDATA,
                           this );
        curl_easy_setopt ( ch, CURLOPT_NOPROGRESS, 0L );
    }
    
    totalUpload   = 0;
    partialUpload = 0;
};

bool easyCURL::setUrl ( const char* url )
{
    curl_easy_setopt ( ch, CURLOPT_URL, url );
    return true;
}

bool easyCURL::setHeader ( const char* header )
{
    customHeader = curl_slist_append ( customHeader,
                                       header );
    curl_easy_setopt ( ch, CURLOPT_HTTPHEADER,
                       customHeader );
    return true;
}

bool easyCURL::IsOK ()
{
    return ( ch == NULL );
}

bool easyCURL::setProxy ( const wxString&
                          proxyServer, long proxyPort /* = 8080 */ )
{
    m_port = proxyPort;
    m_proxy = proxyServer;
    return true;
}

bool easyCURL::setProxyUsername ( const wxString&
                                  proxyUsername, const wxString& proxyPassword )
{
    m_proxyUsername = proxyUsername;
    m_proxyPassword = proxyPassword;
    return true;
}

bool easyCURL::setUploadedFile ( const wxString&
                                 real_filename, const wxString& server_filename,
                                 const wxString& category )
{
    /* Fill in the file upload field */
    curl_formadd ( &formPost,
                   &lastPtr,
                   CURLFORM_COPYNAME, "filedata",
                   CURLFORM_FILE,
                   real_filename.ToStdString ().c_str (),
                   CURLFORM_FILENAME,
                   server_filename.ToStdString ().c_str (),
                   CURLFORM_END );
    /* Fill in the submit field too, even if this is rarely needed */
    curl_formadd ( &formPost,
                   &lastPtr,
                   CURLFORM_COPYNAME, "action",
                   CURLFORM_COPYCONTENTS, "upload",
                   CURLFORM_END );
    curl_formadd ( &formPost,
                   &lastPtr,
                   CURLFORM_COPYNAME, "upload-user",
                   CURLFORM_COPYCONTENTS, "",
                   CURLFORM_END );
    curl_formadd ( &formPost,
                   &lastPtr,
                   CURLFORM_COPYNAME, "upload-text",
                   CURLFORM_COPYCONTENTS, "",
                   CURLFORM_END );
    curl_formadd ( &formPost,
                   &lastPtr,
                   CURLFORM_COPYNAME, "categories-selector",
                   CURLFORM_COPYCONTENTS,
                   category.ToStdString ().c_str (),
                   CURLFORM_END );
    //curl_easy_setopt (ch, CURLOPT_POST, 1L);
    wxULongLong fSize = wxFileName::GetSize (
                            real_filename );
    totalUpload = fSize.ToDouble () ;
    errCode = curl_easy_setopt ( ch, CURLOPT_HTTPPOST,
                                 formPost );
    realFilename = server_filename;
    return errCode == CURLE_OK;
}

size_t easyCURL::ReceiveContent ( void* ptr,
                                  size_t size, size_t nmemb, void* userdata )
{
    easyCURL* curl = reinterpret_cast<easyCURL*>
                     ( userdata );
    curl->curlResponse.Append (
        reinterpret_cast<const char*> ( ptr ),
        size * nmemb );
    return size * nmemb;
}

int easyCURL::UploadProgress ( void* p,
                               double dltotal, double dlnow,
                               double ultotal, double ulnow )
{
    easyCURL* curl = reinterpret_cast <easyCURL*>
                     ( p );
    curl->partialUpload = ulnow ;
    return 0;
}

easyCURL::~easyCURL ()
{
    /* always cleanup */
    curl_easy_cleanup ( ch );
    /* then cleanup the formpost chain */
    curl_formfree ( formPost );
    /* free the custom headers */
    curl_slist_free_all ( customHeader );
}
bool easyCURL::Execute ()
{
    errCode = curl_easy_perform ( ch );
    
    if ( errCode != CURLE_OK ) {
        wxString s;
        s << curl_easy_strerror ( errCode );
        wxMessageBox ( s );
    }
    
    return errCode == CURLE_OK;
}